use crate::config::app_error::AppResult;
use crate::extension::index::index::indexer::DefaultIndexer;
use crate::extension::index::index::query::query::equal::Equal;
use crate::extension::index::index::query::query::{BaseQuery, QueryIndexView};
use halo_model::{ExtensionOperator, GVK};
use ordermap::OrderSet;
use std::hash::Hash;

pub(crate) struct NotEqual {
    pub field_name: String,
    pub value: String,
    pub is_field_ref: bool,
    pub equal: Equal,
}

impl NotEqual {
    pub fn new(field_name: String, value: String) -> Self {
        NotEqual {
            field_name: field_name.clone(),
            value: value.clone(),
            is_field_ref: false,
            equal: Equal {
                field_name,
                value,
                is_field_ref: false,
            },
        }
    }
    pub fn new_ref(field_name: String, value: String, is_field_ref: bool) -> Self {
        NotEqual {
            field_name: field_name.clone(),
            value: value.clone(),
            is_field_ref,
            equal: Equal {
                field_name,
                value,
                is_field_ref,
            },
        }
    }
}

impl BaseQuery for NotEqual {
    fn matches(
        &self,
        index_view: &QueryIndexView<DefaultIndexer>,
    ) -> AppResult<OrderSet<String>> {
        let equal_names = self.equal.matches(index_view)?;
        let mut all_names = index_view.get_all_ids()?;
        all_names.retain(|name| !equal_names.contains(name));
        Ok(all_names)
    }
}
